1 /*
2  * Hunt - a framework for web and console application based on Collie using Dlang development
3  *
4  * Copyright (C) 2015-2017  Shanghai Putao Technology Co., Ltd
5  *
6  * Developer: HuntLabs
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.utils.random;
13 
14 import std.stdio;
15 import std.exception;
16 
17 ubyte[] getRandom(ushort len = 64)
18 {
19 	assert(len);
20 	ubyte[] buffer;
21 	buffer.length = len;
22 	version(Windows){
23 		HCRYPTPROV hCryptProv;
24 		assert(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) != 0);
25 		CryptGenRandom(hCryptProv, cast(DWORD)buffer.length, buffer.ptr);
26 		scope(exit)CryptReleaseContext(hCryptProv, 0);
27 	}else{
28 		import core.stdc.stdio : FILE, _IONBF, fopen, fclose, fread, setvbuf;
29 		auto file = fopen("/dev/urandom","rb");
30 		scope(exit)fclose(file);
31 		if(file is null)throw new Exception("Failed to open /dev/urandom"); 
32 		if(setvbuf(file, null, 0, _IONBF) != 0)throw new 
33 			Exception("Failed to disable buffering for random number file handle");
34 		if(fread(buffer.ptr, buffer.length, 1, file) != 1)throw new
35 			Exception("Failed to read next random number");
36 	}
37 	return buffer;
38 }
39 
40 
41 
42 version(Windows){
43 	static if (__VERSION__ >= 2070)
44 	{
45 		import core.sys.windows.windows;
46 	}
47 	else
48 	{
49 		import std.c.windows.windows;
50 		import std.conv;
51 
52 	}
53 
54 	pragma(lib, "advapi32.lib");
55 
56 	private extern (Windows) nothrow
57 	{
58 		alias HCRYPTPROV = size_t;
59 
60 		enum LPCTSTR NULL = cast(LPCTSTR) 0;
61 		enum DWORD PROV_RSA_FULL = 1;
62 		enum DWORD CRYPT_VERIFYCONTEXT = 0xF0000000;
63 
64 		BOOL CryptAcquireContextA(HCRYPTPROV* phProv, LPCTSTR pszContainer,
65 				LPCTSTR pszProvider, DWORD dwProvType, DWORD dwFlags);
66 		alias CryptAcquireContext = CryptAcquireContextA;
67 
68 		BOOL CryptReleaseContext(HCRYPTPROV hProv, DWORD dwFlags);
69 
70 		BOOL CryptGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE* pbBuffer);
71 	}
72 }